package org.brisling.oa.queryService.base;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.brisling.authorize.shiro.ShiroSecurityService;
import org.brisling.base.domain.ChartDomain;
import org.brisling.base.domain.ExportExcelDomain;
import org.brisling.base.domain.ListDomain;
import org.brisling.base.domain.RetDomain;
import org.brisling.base.service.AbstractBaseQueryService;
import org.brisling.common.ConstSysParam;
import org.brisling.common.SysConfig;
import org.brisling.common.util.ExportUtil;
import org.brisling.common.util.FileUtil;
import org.brisling.common.util.JsonUtil;
import org.brisling.sysman.domain.Permissions;
import org.brisling.sysman.domain.Users;
import org.brisling.sysman.queryService.QueryDictionaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;


/**
 * 
 * <p>Title: AbstractOAQueryService</p>
 * <p>Description: OA查询服务抽象类</p>
 * <p>Company: 长沙东勤信息科技发展有限公司</p>
 * @author jackson wang
 * @since 1.0
 * @version 1.0
 * @date 2016年7月9日 上午12:31:45
 */

public abstract class AbstractOAQueryService<T> extends AbstractBaseQueryService<T>{
	
	
	
	@Autowired
	protected ShiroSecurityService shiroSecurityService;
	@Autowired
	protected QueryDictionaryService dicService;
	
	protected static final String USER_CODE = "apply_id";
	
	protected static final String DEPT_CODE = "apply_deptid";
	
	protected static final String QUERY_BIZ_ALL_CODE = "query_oa_all";
	
	protected String print_model_path = "d:/upload/print/oa/";
	
	
	protected AbstractOAQueryService(){
		orderMap.put("apply_date","desc");
		orderMap.put("bizno","desc");
	}
	
	/**
	 * 获取实体列表信息
	 */
	protected ListDomain<T> getListDomain(
			@RequestBody(required=false) String body){		
		
		return super.getListDomainByConditionAndOrder(body, typeMap, orderMap,true);
	}
	
	/**
	 * 获取用户可操作事项记录
	 * @param body
	 * @return
	 */
	protected ListDomain<T> getUserCanoperateTask(@RequestBody(required=false) String body){
		String sql = dicService.getSqlByBizcode("flow_can_operate");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		Map<String,Object> conditionMap = this.getBodyParam(body);
		return super.getUserTaskCanOperateListDomain(userid,sql, conditionMap);
	}
	
	/**
	 * 获取用户已签收事项记录集合
	 * @param body
	 * @return
	 */
	protected ListDomain<T> getUserSignedTask(@RequestBody(required=false) String body){
		String sql = dicService.getSqlByBizcode("flow_signed");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		Map<String,Object> conditionMap = this.getBodyParam(body);
		return super.getUserSignedListDomain(userid,sql, conditionMap,null);
	}
	
	/**
	 * 获取用户待签收事项记录集合
	 * @param body
	 * @return
	 */
	protected ListDomain<T> getUserUnsignedTask(@RequestBody(required=false) String body){
		String sql = dicService.getSqlByBizcode("flow_can_signed");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		Map<String,Object> conditionMap = this.getBodyParam(body);
		return super.getUserUnsignedListDomain(userid,sql, conditionMap,null);
	}
	
	
	/**
	 * 获取已完成事项记录集合
	 * @param body
	 * @return
	 */
	protected ListDomain<T> getUserFinishedTask(@RequestBody(required=false) String body){
		String sql = dicService.getSqlByBizcode("flow_finished");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		Map<String,Object> conditionMap = this.getBodyParam(body);
		if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, QUERY_BIZ_ALL_CODE))
			conditionMap = this.addDeptConditionToMap(userid,conditionMap, DEPT_CODE);
			
		return super.getUserFinishedListDomain(sql, conditionMap,null);
	}
	
	
	/**
	 * 获取所有事项记录集合
	 * @param body
	 * @return
	 */
	protected ListDomain<T> getAllTask(String body){
		String sql = dicService.getSqlByBizcode("flow_all_task");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		Map<String,Object> conditionMap = this.getBodyParam(body);
		if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, QUERY_BIZ_ALL_CODE)){
			
			String fullBizcode = null;
			if(conditionMap.containsKey("bizcode")){
				Object obj = conditionMap.get("bizcode");
				if(obj!=null){
					String bizcode = obj.toString();
					if(SysConfig.getFlowBizcodeMap()!=null){
						Permissions p =  SysConfig.getFlowBizcodeMap().get(bizcode);
						if (p!=null && p.getFullBizcode()!=null){
							fullBizcode= p.getFullBizcode();
						}
					}
				}
			}
			
			if((fullBizcode==null)||(!this.isBizManageDept(userid, fullBizcode))){
				if(!this.isManageJob(userid)){
					conditionMap = this.addUsridConditionToMap(userid, conditionMap, USER_CODE);
				}else{
					conditionMap = this.addDeptConditionToMap(userid,conditionMap, DEPT_CODE);
				}
				
			}
		}
			
		return super.getAllListDomain(sql, conditionMap,null);
	}
	
	
	/**
	 * 用户管理的事项记录集合
	 * @param body
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected ListDomain<T> getUserManagedTask(@RequestBody(required=false) String body){
		String sql = dicService.getSqlByBizcode("flow_managed_manageuser");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		Map<String,Object> conditionMap = this.getBodyParam(body);
		if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, QUERY_BIZ_ALL_CODE)){
			Users usr = SysConfig.getUsr(userid);
			if(this.isManageJob(userid)){
				conditionMap = this.addDeptConditionToMap(userid,conditionMap, DEPT_CODE);
			}else{
				Map<String,String> paramMap = (Map<String, String>) conditionMap.get(ConstSysParam.CONDITION_MAP_KEY);
				if(paramMap==null){
					paramMap = new HashMap<String,String>();
				}
				paramMap.put("user_id_", usr.getIdentify());
				conditionMap.put(ConstSysParam.CONDITION_MAP_KEY, paramMap);
				sql = dicService.getSqlByBizcode("flow_managed_normaluser"); 
			}
		}
		return super.getUserManagedListDomain(sql, conditionMap,null);
	}
	
	/**
	 * 导出excel格式数据集合
	 * @param body		参数
	 * @param response	servlet响应对象
	 * @param title		导出excel title
	 * @param sqlid		sql语句代码
	 */
	protected void exportExcel(@RequestBody(required=false) String body,HttpServletResponse response,String title,String sqlid){
		ListDomain<T> domains= this.getAllTask(body);
		String configStr = dicService.getSqlByBizcode(sqlid);
		
		ObjectMapper mapper = JsonUtil.getMapper();
		JavaType _javaType = mapper.getTypeFactory().constructCollectionType(List.class, ExportExcelDomain.class);

		List<ExportExcelDomain> list = null;
		try {
			list =  mapper.readValue(configStr, _javaType);
		}catch(Exception e){
			e.printStackTrace();
		}
		ExportUtil<T> eu = new ExportUtil<T>(title,list,domains.getRows());
		try {
			eu.exportByDomain(response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 导出excel格式已完成数据集合
	 * @param body		参数
	 * @param response	servlet响应对象
	 * @param title		导出excel title
	 * @param sqlid		sql语句代码
	 */
	protected void exportExcelFinished(@RequestBody(required=false) String body,HttpServletResponse response,String title,String foot,String sqlid){
		ListDomain<T> domains= this.getUserFinishedTask(body);
		String configStr = dicService.getSqlByBizcode(sqlid);
		super.exportExcel(domains, response, title, foot, configStr);
		
	}
	
	/**
	 * 获取任务集合
	 * @param body
	 * @return
	 */
	protected ListDomain<T> getTaskListDomain(@RequestBody(required=false) String body){
		
		
		ListDomain<T> domains = new ListDomain<T>();
		Map<String,Object> conditionMap = this.getBodyParam(body);
		if((conditionMap!=null) && (conditionMap.containsKey("condition"))){
			@SuppressWarnings("unchecked")
			Map<String,String> cMap = (Map<String, String>) conditionMap.get(ConstSysParam.CONDITION_MAP_KEY);
			String _state = null;
			if((cMap!=null) && (cMap.containsKey("flow_state"))){
				_state = cMap.get("flow_state");				
			}else{
				_state = ConstSysParam.FLOW_CANOPERATE;
			}			
			switch(_state){
			case ConstSysParam.FLOW_CANOPERATE:
				domains = getUserCanoperateTask(body);
				break;
//			case ConstSysParam.FLOW_SIGNED:
//				domains = getUserSignedTask(body);
//				break;
//			case ConstSysParam.FLOW_UNSIGED:
//				domains = getUserUnsignedTask(body);
//				break;
			case ConstSysParam.FLOW_MANAGED:
				domains = getUserManagedTask(body);
				break;
			case ConstSysParam.FLOW_FINISHED:
				domains = getUserFinishedTask(body);
				break;
			case ConstSysParam.FLOW_all:
				domains = getAllTask(body);
				break;
			default:
				domains = getUserCanoperateTask(body);
				break;
			}
		}
		return domains;
	}
	
	/**
	 * 获取任务数量
	 * @return
	 */
	
	protected List<ChartDomain> getTaskCnt(@RequestBody(required=false) String body){
		
		List<ChartDomain> domains = new ArrayList<ChartDomain>();
		String issue = "medical";
		Long canOpera = null;
		Long managed = null;
		Long finished = null;
		ListDomain<T> inquirys = this.getUserCanoperateTask(null);
		
		canOpera = inquirys.getTotal();
		ChartDomain operate = new ChartDomain("待处理",issue,canOpera);
		domains.add(operate);
		
		inquirys = this.getUserManagedTask(null);
		managed = inquirys.getTotal();
		ChartDomain manage = new ChartDomain("处理中",issue,managed);
		domains.add(manage);
		
		inquirys = this.getUserFinishedTask(body);
		finished = inquirys.getTotal();
		ChartDomain finish = new ChartDomain("已处理",issue,finished);
		domains.add(finish);
		
		return domains;
		
	}
	
	
	/**
	 * 根据id查找任务信息
	 * @param id	任务id
	 * @return 事项记录 
	 */
	
	protected T getOne(@RequestParam(value="id",required=false) Long id){
		return super.getOne(id);
	}
	
	/**
	 * 根据唯一编码查找事项信息
	 * @param identify	事项唯一编码
	 * @return 事项信息记录
	 */
	
	protected T getOneByIdentify(@RequestParam(value="identify",required=false) String identify){	
		return super.getOneByIdentify(identify);
	}
	
	/**
	 * 根据字段值查找事项记录
	 * @param field		字段名称
	 * @param fieldVal	字段值
	 * @return
	 */
	
	protected T getOneByField(@RequestParam(value="field",required=false) String field,
			@RequestParam(value="fieldVal",required=false) String fieldVal){	
		return super.getOneByIdentify(field,fieldVal);
	}
	
	
	
	/**
	 * 返回流程记录流程实例的执行记录
	 * @param body	包含procInstId在内的参数信息
	 * @return
	 */
	
	protected ListDomain<Object> getHistoricByProcInstId(@RequestBody(required=false) String body){
		
		String sql = dicService.getSqlByBizcode("flow_historics");				
		return super.getHistoricByProcInstId(body, sql);
	}
	
	public String generateBizno(){
		return super.generateBizno();
	}
	
	
	/**
	 * 导出word文档
	 * @param id
	 * @return
	 */
	protected RetDomain exportWord(@RequestParam(value="id",required=false) Long id,String moduleCode,HttpServletResponse response,String outfileName){
		
		RetDomain r = new RetDomain();
		if(id!=null){
			T t = this.getClassedOne(this.moduleName, id.toString(), clazz);			 
			r = exportWord(t,moduleCode,response,outfileName);
		}
		return r;
	}
	
	/**
	 * 导出word文档
	 * @param body
	 * @return
	 */
	protected RetDomain exportWord(@RequestBody(required=false) String body,String moduleCode,HttpServletResponse response,String outfileName){
		
		RetDomain r = new RetDomain();
		if(body!=null){
			T t = this.bodyToObj(body, clazz);
			r = exportWord(t,moduleCode,response,outfileName);
		}
		return r;
	}
	
	/**
	 * 导出word文档
	 * @param t
	 * @return
	 */
	protected RetDomain exportWord(T t,String moduleCode,HttpServletResponse response,String outfileName){
		
		RetDomain r = new RetDomain();
		
		String fileName = outfileName==null?"审批单":outfileName;
		
		String s = JsonUtil.objToJson(t);
		
		@SuppressWarnings("unchecked")
		Map<String,Object> obj = JsonUtil.body2Class(s, Map.class);
		
		String encodefilename = null;
		try {
			encodefilename = URLEncoder.encode(fileName+".doc","UTF-8");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		response.addHeader("Content-Disposition", "attachment; filename="+encodefilename);
		
		response.setCharacterEncoding("UTF-8");	
//		response.setCharacterEncoding("GBK");	
		
		response.setContentType("application/octet-stream");
		
		
		String fp = this.print_model_path+moduleCode+".xml";
		try {
			FileUtil.exportWord(obj,fp,response.getOutputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return r;
	}
	

}
